package com.easyapi.config;

import com.easyapi.controller.execute.GenerateInterfaceBaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

@Configuration
public class DynamicApiConfig implements WebMvcConfigurer {

    private final RequestMappingHandlerMapping handlerMapping;
    private final ApplicationContext applicationContext;

    @Autowired
    @Lazy
    public DynamicApiConfig(@Lazy RequestMappingHandlerMapping handlerMapping,
                            @Lazy ApplicationContext applicationContext) {
        this.handlerMapping = handlerMapping;
        this.applicationContext = applicationContext;
    }

    private void registerDynamicApiRoutes(List<String> paths, RequestMethod method) throws NoSuchMethodException {
        GenerateInterfaceBaseController bean = applicationContext.getBean(GenerateInterfaceBaseController.class);
        String[] pathArray = paths.toArray(new String[0]);

        handlerMapping.registerMapping(
                RequestMappingInfo.paths(pathArray).methods(method).build(),
                bean,
                GenerateInterfaceBaseController.class.getDeclaredMethod(
                        "generateInterfacePostExecute", Map.class, HttpServletRequest.class)
        );
    }

    public List<String> getAlreadyRegistered(RequestMethod method) {
        Map<RequestMappingInfo, HandlerMethod> handlerMethods = handlerMapping.getHandlerMethods();
        List<RequestMappingInfo> collected = handlerMethods.keySet()
                .stream()
                .filter(m -> m.getMethodsCondition().getMethods().contains(method))
                .collect(Collectors.toList());
        List<String> list = new ArrayList<>();
        for (RequestMappingInfo requestMappingInfo : collected) {
            if (requestMappingInfo.getPatternsCondition() != null) {
                List<String> collect = new ArrayList<>(requestMappingInfo.getPatternsCondition().getPatterns());
                list.addAll(collect);
            }
        }
        return list;
    }

    public void registerDynamicApiRoutesPOST(List<String> paths) throws NoSuchMethodException {
        registerDynamicApiRoutes(paths, RequestMethod.POST);
    }

    public void registerDynamicApiRoutesGET(List<String> paths) throws NoSuchMethodException {
        registerDynamicApiRoutes(paths, RequestMethod.GET);
    }


    private void unregisterDynamicApiRoutes(List<String> paths, RequestMethod method) {
        for (String path : paths) {
            // 构建 RequestMappingInfo
            RequestMappingInfo mappingInfo = RequestMappingInfo
                    .paths(path)
                    .methods(method)
                    .build();

            // 从 handlerMapping 中移除映射
            handlerMapping.unregisterMapping(mappingInfo);
        }
    }

    public void unregisterDynamicApiRoutesPOST(List<String> paths) {
        unregisterDynamicApiRoutes(paths, RequestMethod.POST);
    }

    public void unregisterDynamicApiRoutesGET(List<String> paths) {
        unregisterDynamicApiRoutes(paths, RequestMethod.GET);
    }
}
